package cn.jdemo.juc.CompletableFuture;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 【对象方法】
 *
 * whenComplete 和 whenCompleteAsync 的区别：
 * whenComplete：是执行当前任务的线程执行继续执行 whenComplete 的任务。
 * whenCompleteAsync：是执行把 whenCompleteAsync 这个任务继续提交给线程池来进行执行。
 *
 * 注:when代表主体执行完后，才执行后续的when
 *
 * link：https://www.jianshu.com/p/6bac52527ca4
 * @date 2020/12/1
 *Demo01
 */
public class Demo02 {

    private static final ExecutorService es = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()*2);

    public static void main(String[] args) throws Exception {
        Demo02.test01();
    }

    /**
     * 代码执行顺序:
     * *************whenComplete:start***************
     * *************whenComplete:end***************
     * pool-1-thread-1 : num1
     * pool-1-thread-2 : num4
     * pool-1-thread-3 : num2
     * pool-1-thread-3 : num3
     * @throws Exception
     */
    public static void test01()throws Exception{

        CompletableFuture<Void> future1 = CompletableFuture.runAsync(() -> {
            try {
                Thread.sleep(2000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + " : num1");

        }, es);

        CompletableFuture<Void> future2 = future1.whenCompleteAsync((x, y) -> {
            try {
                Thread.sleep(5000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + " : num2");
        }, es);

        System.out.println("*************whenComplete:start***************");
        future2.whenComplete((a,b)->{
            System.out.println(Thread.currentThread().getName() + " : num3");
        });
        System.out.println("*************whenComplete:end***************");

        CompletableFuture<Void> future4 = future1.whenCompleteAsync((x, y) -> {
            try {
                Thread.sleep(2000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + " : num4");
        }, es);
    }

}
